package com.itheima.tlias.aspect;

import com.alibaba.fastjson2.JSONObject;
import com.itheima.tlias.mapper.EmpMapper;
import com.itheima.tlias.pojo.entity.Emp;
import com.itheima.tlias.pojo.entity.Log;
import com.itheima.tlias.service.EmpService;
import com.itheima.tlias.service.LogService;
import com.itheima.tlias.utils.JwtUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.time.Instant;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Date;
import java.util.Objects;

@Slf4j
@Aspect
@Component
public class LogAspect {
    @Resource
    private LogService logService;
    @Resource
    private HttpServletRequest request;
    @Resource
    private EmpMapper empMapper;
    
    //ProceedingJoinPoint 连接点对象
    
    @Around("@annotation(com.itheima.tlias.annotation.Log)")
    public Object insertLog(ProceedingJoinPoint point){

        String token = request.getHeader("token");
        if(Objects.isNull(token)){
        }
        JSONObject jsonObject = JwtUtil.verifyToken(token);
        Emp emp = empMapper.selectEmpByName(jsonObject.get("username").toString());
        //操作人
        String operateEmpName = emp.getUsername();
        //操作人ID
        int operateEmpId = emp.getId();

        //操作时间
        LocalDateTime operateTime =  LocalDateTime.now();
        //类名
        String className = point.getTarget().getClass().getName();
        //方法名
        String methodName = point.getSignature().getName();
        //请求参数
        String methodParams = Arrays.toString(point.getArgs());

        //执行父类方法
        Object proceed;
        //操作耗时
        long costTime = 0L;
        try {
            long start = System.currentTimeMillis();
            proceed = point.proceed();
            costTime = System.currentTimeMillis() - start;
            log.info("操作{}方法插入日志",point.getSignature().getName());
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
        //返回值
        String returnValue = proceed.toString();

        Log logE = new Log();
        logE.setOperateEmpId(operateEmpId);
        logE.setOperateEmpName(operateEmpName);
        logE.setOperateTime(operateTime);
        logE.setClassName(className);
        logE.setMethodName(methodName);
        logE.setMethodParams(methodParams);
        logE.setReturnValue(returnValue);
        logE.setCostTime(costTime);
        int flag = logService.insertLog(logE);
        if(flag == 1){
            log.info("操作{}方法插入日志成功",point.getSignature().getName());
        }else{
            log.info("操作{}方法插入日志失败",point.getSignature().getName());
        }
        return proceed;
    }
}
